package org.langke.java.base.stream;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

/**
 * 参考：https://www.jianshu.com/p/17d432f211f4
 * 使用Java8新特性parallelStream遇到的坑
 * stream线程安全
 */
public class ListParalleStreamTest {
    public static void main0(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<Calendar> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            Calendar startDay = new GregorianCalendar();
            Calendar checkDay = new GregorianCalendar();
            checkDay.setTime(startDay.getTime());//不污染入参
            checkDay.add(Calendar.DATE,i);
            list.add(checkDay);
            checkDay = null;
            startDay = null;
        }

        list.stream().forEach(day ->  System.out.println(sdf.format(day.getTime())));
        System.out.println("-----------------------");
        list.parallelStream().forEach(day ->  System.out.println(sdf.format(day.getTime())));
        System.out.println("-----------------------");
    }
    public static void main1(String[] args) {
        DateTimeFormatter fmt =  DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate date = LocalDate.now();
        List<LocalDate> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            LocalDate date1 = date.plusDays(i);
            list.add(date1);
        }
        list.stream().forEach(day ->  System.out.println(day.format(fmt)));
        System.out.println("-----------------------");
        list.parallelStream().forEach(day ->  System.out.println(day.format(fmt)));
    }

    public static void main2(String[] args) {
        DateTimeFormatter fmt =  DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDateTime date = LocalDateTime.now();
        List<LocalDateTime> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            LocalDateTime date1 = date.plusDays(i);
            list.add(date1);
        }
        list.stream().forEach(day ->  System.out.println(day.format(fmt)));
        System.out.println("-----------------------");
        list.parallelStream().forEach(day ->  System.out.println(day.format(fmt)));
    }

    public void processList(List<String> list,List<String> odd,List<String> even){
        for (int i = 1; i <= 100; i++) {
            list.add(i+"");
        }
        list.parallelStream().forEach(s -> {
            if(Integer.valueOf(s) % 2 ==0){
                even.add(s);
            }else{
                odd.add(s);
            }
        });
        System.out.printf("odd:%s even:%s \n",
                odd.stream().distinct().collect(Collectors.toList()).size(),
                even.stream().distinct().collect(Collectors.toList()).size());
        odd.stream().forEach(s -> System.out.printf("%s ",s));
        System.out.println();
        even.stream().forEach(s -> System.out.printf("%s ",s));
    }

    public void testArrayList(){
        List<String> odd = new ArrayList<>();
        List<String> even = new ArrayList<>();
        List<String> list = new ArrayList<>();
        processList(list,odd,even);
    }

    public void testArrayListSync(){
        List<String> odd = Collections.synchronizedList(new ArrayList<>());
        List<String> even = Collections.synchronizedList(new ArrayList<>());
        List<String> list = Collections.synchronizedList(new ArrayList<>());
        processList(list,odd,even);
    }


    public void testCopyOnWriteArrayList(){
        CopyOnWriteArrayList<String> odd = new CopyOnWriteArrayList<>();
        CopyOnWriteArrayList<String> even = new CopyOnWriteArrayList<>();
        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
        processList(list,odd,even);
    }
    public static void main(String[] args) {
        ListParalleStreamTest test = new ListParalleStreamTest();
        test.testArrayList();
        System.out.println("\n");
        test.testArrayListSync();
        System.out.println("\n");
        test.testCopyOnWriteArrayList();
    }

}
